﻿module TestApp

open System
open System.Diagnostics
open System.Reactive.Disposables 
open System.Reactive.Linq
open System.Linq
open System.IO
open Operators.Unchecked 

open com.ib.client

open Trading.IBApi
open Trading

let tradeTick (contract : Contract) (ibapi : IBrokerGateway) = 
    let source = ibapi.Ticks contract |> Observable.iterThrough (printfn "\tTick: %O") 
    source.Publish(
        fun source' ->
            let lastSize = 
                source'
                |> Observable.choose (function | Volume x -> Some x | _ -> None)
                |> Observable.pairwise 
                |> Observable.map (fun(prev, current) -> current - prev)

            let lastPrice = 
                let prices = source' |> Observable.choose (function | LastPrice x -> Some x | _ -> None)
                //let initialValue = prices.First()
                prices
                    .MostRecent(initialValue = Double.NaN)
                    //.Where(fun x -> x <> Double.NaN)

            lastSize.Zip(lastPrice, fun size price -> contract.m_localSymbol, DateTime.Now, price, size)
    )

type IBrokerGateway with
    static member FromFile(file : FileInfo) = 
        { 
            new IBrokerGateway with
                member this.Ticks _ =
                    let result = 
                        seq {
                            use reader = file.OpenText()
                            while not reader.EndOfStream do
                                let line = reader.ReadLine().Trim()
                                if line <> "" then
                                    yield Tick.Parse line
                        } 
                        |> Seq.toArray 
                    result.ToObservable() 

                member this.ConnectionInfo = undefined
                member this.Errors = undefined
                member this.ContractDetails _ _ = undefined
                member this.PlaceOrder(contract, order) = undefined
                member this.HistoricalData(_,_,_,_,_,_) = undefined
                member this.RealTimeBars(_,_,_) = undefined

        }
            

(* 
    /simulation C:\Users\dmitry.morozov\TradingBot\mudila-babashkin\Trading\TestApp\bin\Debug\mail.txt 
*)


[<EntryPoint>] 
let main args =
    use resource = new MutableDisposable()
    let client : IBrokerGateway = 
        match args with
            | [|"/simulation"; fileName|] -> 
                let file = FileInfo fileName
                IBrokerGateway.FromFile file
            | _ ->
                let x = new JSharpClient(host = "10.90.132.58", port = 4001, clientId = 11)
                resource.Disposable <- x
                upcast x

    client.Errors.Add(printfn "Error: %O")
    
    let apple = Contract(m_symbol = "AAPL", m_expiry = "20110513", m_right = "C", m_strike = 345., m_exchange = "SMART", m_secType = "OPT")
    //let apple = Contract(m_localSymbol = "AAPL  110429C00350000", m_exchange = "SMART", m_secType = "OPT");
    //let google = Contract(m_localSymbol = "GOOG  110421C00540000", m_exchange = "SMART", m_secType = "OPT");
    let google = Contract(m_symbol = "GOOG", m_expiry = "20110513", m_right = "C", m_strike = 540., m_exchange = "SMART", m_secType = "OPT")
    //let qqq = Contract(m_symbol = "QQQ", m_expiry = "20110527", m_right = "C", m_strike = 57., m_exchange = "SMART", m_secType = "OPT")
    //let qqq = Contract(m_symbol = "QQQ", m_exchange = "SMART", m_secType = "STK", m_currency = "USD")
    let aapl = Contract(m_symbol = "AAPL", m_exchange = "SMART", m_secType = "STK", m_currency = "USD")
    let goog = Contract(m_symbol = "GOOG", m_exchange = "SMART", m_secType = "STK", m_currency = "USD")

    //client.Ticks goog |> Observable.add (printfn "%O")

//    let aapl = Contract(m_symbol = "AAPL", m_exchange = "SMART", m_secType = "STK", m_currency = "USD")
    //resources.Add(tradeTick apple ibapi  |> Observable.subscribe(printfn "%O"))
    //resources.Add(tradeTick google ibapi |> Observable.subscribe(printfn "%O"))

//    printfn "Press <Enter> to stop ticks"
//    stdin.ReadLine() |> ignore
//    resources.Dispose()

//    async {
//        let noStrikeContract = 
//            Contract(m_symbol = "GOOG", m_expiry = "20110513", m_right = "C", m_exchange = "SMART", m_secType = "OPT")
//        let! strikes = client.OptionStrikes noStrikeContract
//        return strikes 
//    } 
//    |> Async.RunSynchronously 
//    |> Enumerable.ToArray 
//    |> printfn "%A"

    //let l = client.CreateComboLeg(apple, Buy) |> Async.RunSynchronously

    // Test for Historical data request
//    let x = 
//        [bidu]
//        |> List.map (fun symbol -> client.HistoricalData (symbol, DateTime.Parse "2011/05/13 16:15:00", span = (3, Days), barSize = Bar4Hours, whatToShow = "TRADES"))
//        |> Async.Parallel 
//        |> Async.RunSynchronously
//        //|> (fun x -> x.[0].Length |> printfn "%d")
//        |> printfn "%A"

//    let x = [bidu] |> List.map (fun contract -> client.RealTimeBars(contract, whatToShow = "TRADES"))
//    let y = x |> Async.Parallel
//    let z = y |> Async.RunSynchronously
//    let a = z |> (fun x -> x.[0].Length |> printfn "%d")
//        //|> printfn "%A"
    // Test for Realtime Bars
//    let newbar (x: RealTimeBar) =
//        printfn "Trades: %A" x
//
//    let bars = client.RealTimeBars(aapl, "TRADES") |> Observable.subscribe (newbar)
//    
//    //let bars = client.RealTimeBars(aapl, "TRADES") |> fun x -> x.Buffer(count=2, skip=1) |> Observable.subscribe(printfn "%A")
//    printfn "Press <Enter> to stop"
//    stdin.ReadLine() |> ignore
//    bars.Dispose()
    printfn "Press <Enter> to start"
    stdin.ReadLine() |> ignore
    TickRecorder.recordRTTicks client @".\" 23400 goog
    0


